CloudFront+ALB+EC2の構成でApacheのVirtualHostを使いドメインごとに別のページを表示させる
どうもさいちゃんです。
EC2 インスタンス上で Apache の VirtualHost を使用して 2 つのドメインから WEB サイトを参照している場合でも、コンテンツキャシュやセキュリティ上の要件から CloudFront を使いたい場合があるかと思います。今回は、CloudFront + ALB + EC2 の構成で Apache の VirtualHost を使用する方法についてご紹介します。
実現したい構成
今回は VirtualHost でsite1.xxx.com
とsite2.xxx.com
という 2 つのドメインからのアクセスに対してそれぞれ別のページを表示させる設定を行います。
今回は別のページを表示させる想定ですが、Apache で片方のドメインへのリダイレクトを設定すれば、この方法でドメインのリダイレクトをさせることも可能です。
CloudFront と ALB が前段にある状態で、想定の挙動をさせる為に今回は下記のような構成を取ることにしました。
CloudFront に代替ドメインとしてsite1.xxx.com
とsite2.xxx.com
の二つのドメインを登録し、DNS サーバーの設定を行います。
上記の設定でどちらのドメインも名前解決の先が CloudFront となります。
指定のドメインへのアクセスは CloudFront と ALB を経由して EC2 へ到達。Apache の VirtualHost 設定に従い、それぞれの指定のページを表示させるイメージです。
EC2 の設定
今回使用した OS は Linux2023 です。テスト用なのでインスタンスタイプは t2.micro としています。
名前は分かりやすいものを付ければ OK です。今回は「Vatualhost-test-Instance」とします。
適切な VPC とサブネットを選択します。今回 EC2 へのアクセスは SSM のセッションマネージャーを使用するのでキーペアは指定していません。SSH 接続やポートフォワーディングを行う場合は指定してください。
セキュリティグループについては、ALB-EC2 間の通信は HTTP で問題ないので今回は ALB のセキュリティグループからの HTTP を許可する設定としています。ここは適切なルールを設定してください。
Apache インストール
作成した EC2 へ接続して Apache の VirtualHost の設定を行っていきます。
まずパッケージリストを更新します
$ sudo dnf -y update
下記コマンドで Apache のインストールを行います。
$ sudo dnf -y install httpd
Complite! と表示されていれば無事インストールはできているはずです。念のためバージョン確認をしてみましょう。
$ httpd -v
Server version: Apache/2.4.62 (Amazon Linux)
Server built: Jul 23 2024 00:00:00
問題ないですね。
では、Apache を起動させます。
$ sudo systemctl start httpd
起動しているかの確認を行います。
$ sudo systemctl status httpd.service
実行結果が下記の様に 「active (running) 」 となっていれば Apache が起動しています。
#実行結果
httpd.service - The Apache HTTP Server
Loaded: loaded (/usr/lib/systemd/system/httpd.service; disabled; preset: disabled)
Active: active (running) since Tue 2024-11-26 07:01:47 UTC; 2s ago
...以下略
Apache VirtualHost 設定
ドキュメントルートに各ドメイン用にそれぞれディレクトリを作成します。
$ cd /var/www/html/
$ sudo mkdir site1.xxx.com
$ sudo mkdir site2.xxx.com
各ディレクトリに適当な html ファイルを置きます。
今回はさくっと生成 AI にテストサイト用の HTML ファイル作製をしてもらいました。
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>テストサイト1</title>
<style>
body {
font-family: Arial, sans-serif;
background-color: #f0f0f0;
color: #333;
}
header {
background-color: #4caf50;
color: white;
padding: 10px 0;
text-align: center;
}
main {
padding: 20px;
}
footer {
background-color: #4caf50;
color: white;
text-align: center;
padding: 10px 0;
position: fixed;
width: 100%;
bottom: 0;
}
</style>
</head>
<body>
<header>
<h1>テストサイト1へようこそ</h1>
</header>
<main>
<p>これはテストサイト1のメインコンテンツです。</p>
<p>ここにはいくつかのサンプルテキストが含まれています。</p>
</main>
<footer>
<p>© 2023 テストサイト1</p>
</footer>
</body>
</html>
上記と同じようなものを site2.xxx.com 用のディレクトリにも作成しておきましょう。
次にhttpd.conf
を編集してホスト名に応じて適切なサイトを表示させるように設定をします。
$ cd /etc/httpd/conf
$ sudo vi httpd.conf
httpd.conf
に下記設定を追加します。
<VirtualHost *:80>
ServerName site1.xxx.com
DocumentRoot /var/www/html/site1.xxx.com
ErrorLog /var/www/html/site1.xxx.com-error.log
CustomLog /var/log/httpd/site1.said.xxx.com-access.log combined
</VirtualHost>
<VirtualHost *:80>
ServerName site2.xxx.com
DocumentRoot /var/www/html/site2xxx.com
ErrorLog /var/log/httpd/site2.xxx.com-error.log
CustomLog /var/log/httpd/site2.said.xxx.com-access.log combined
</VirtualHost>
最後に下記コマンドで Apache を再起動します。
$ sudo systemctl restart httpd
ALB の設定
CloudFront も同様なのですが、上記の設定を行うことで VirtualHost 側でドメインによって表示するコンテンツを自動的に振り分けてくれるので特に変わった設定は必要ありません。
CloudFront と ALB は各ドメインへのアクセスを問題なく EC2 まで届けてあげることが出来ればよいのです。
セキュリティグループの作成
さっそく、ALB 用のセキュリティグループを作成します。
インバウンドは CloudFront のプレフィックスリストからの HTTPS のみを許可する設定にしました。
アウトバウンドは EC2 への HTTP が許可されていれば問題ないので、今回はアウトバウンドは全開放で設定しています。
ターゲットグループの作成
ターゲットタイプはインスタンスを選択し、適当なターゲットグループ名を付けます。今回は 「VirtualHost-test-tg」としました。
プロトコルは HTTP:80 を使用、適切な VPC を選び、他の設定はデフォルトで作成します。
先ほど作成した EC2 を選択し、保留中として以下を含めるをクリックします。
ターゲットに対象のインスタンスが含まれていれば問題ありません。そのまま作成します。
ALB の作成
ターゲットグループの設定が完了したので、ロードバランサーを作成していきます。
ロードバランサーのタイプは ALB を選択します。
名前は「VirtualHost-test-ALB」とし、クライアントからのリクエストに関する検証なので、スキームはインターネットを選択しました。
適切な VPC とサブネット(パブリック)を選択し、先ほど作成したセキュリティグループを指定します。
リスナーとリスナールールは外部から来たアクセスをどのように処理するのかを決めたルールです。
今回は CloudFront から来た HTTPS アクセスを EC2 へ転送したいので、プロトコルとポートは HTTPS:443 として、デフォルトのアクションは先ほど作成したターゲットグループへ転送とします。
リスナーのプロトコルに HTTPS を指定しているので証明書を紐づける必要があります。
今回は ACM で証明書を作成しました。(証明書の作成については本ブログの趣旨と少しずれるので割愛します。)
作成した証明書を選択します。
検証用なので WAF や GlobalAccelerator の設定はなしで作成します。
CloudFront の設定
ALB の作成が終わったので CloudFront を作成していきます。
Origin には先ほど作成した ALB を指定します。プロトコルは HTTPS のみとします。
今回作成する CloudFront は検証用でキャッシュはさせたくないので、キャッシュポリシーは「ChachingDisabled」を選択しましたが、要件に合わせて最適なポリシーへ変更してください。
設定の代替ドメイン名の項目で、先ほど VirtualHost 側で設定した2つのドメインを指定します。
SSL 証明書は ALB 同様 ACM で作成したものを使用しています。
そのほかの設定はデフォルトにしましたが、適切なログ配信先を設定しておけば後からログを確認できるので、設定しておくといいかもしれません。
DNS の設定
CloudFront に代替ドメインを設定するには CloudFront のディストリビューション名(ドメイン)と代替ドメインとして登録したドメインを紐づける作業が必要です。
外部の DNS サーバーを使用している場合は CloudFront のディストリビューション名(ドメイン)をそれぞれのドメインに CNAME レコードとして登録します。
Route53 を使用する場合は A レコードで送信先をエイリアスで指定することが出来ます。
これは Route53 のうれしい機能の一つです。
ユーザーがリクエストを送ると CloudFront は最もレイテンシーが低いエッジロケーションの IP を返すようになっています。コンテンツ配信のパフォーマンスを保つためのこの仕組みがあるため、CloudFront が返す IP アドレスを固定することはできません。
CloudFront には固定の IP がないため A レコードとして登録が出来ないのです。
Route53 を使用すれば、本来 CNAME レコードを登録できないネイキッドドメインの場合でも CloudFront を A レコードとして登録が出来きます。これはかなりうれしい機能です。
実際にやってみましょう。
適切なレコード名を入力し、レコードタイプは A レコードでエイリアスをオンにします。
するとトラフィックのルーティング先を選択できるようになるので適切な CloudFront ディストリビューションを指定してあげれば、DNS 側の設定は完了です。
同じようにsite2.xxx.com
にもレコードを追加して CloudFront を向けてあげます。
DNS の設定反映までには少し時間がかかるので、気長に待ちましょう。
テスト結果
ではさっそくそれぞれのドメインでサイトへアクセスしてみましょう
まずはsite1.xxx.com
です。
次にsite2.xxx.com
へアクセスしてみましょう。
それぞれのドメインで意図した別のページを表示出来ましたね。
終わりに
CloudFront + ALB + EC2 の構成で Apache の VatualHost を使用して 1 台の EC2 でドメインごとに別のページを表示させる方法についてご紹介しました。
今回は別のページを表示させる想定ですが、Apache で片方のドメインへのリダイレクトを設定すれば、この方法でドメインのリダイレクトをさせることも可能です。
上記については ALB を使用したリダイレクトの方法を今後ブログ化予定です。興味のある方はそちらもご確認いただければと思います。